using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using System.ComponentModel;

namespace WPRotator
{

    /// <summary>
    /// Summary description for FrmMain
    /// </summary>
    public class FrmMain : Form
    {
        public const int SPI_SETDESKWALLPAPER = 20;
        public const int SPIF_SENDCHANGE = 0x2;
        public int picIndex;

        private OpenFileDialog openFileDialog1;
        private IContainer components;
        private CheckedListBox mycheckedListBox;
        private Button btnDel;
        private Timer timer1;
        private string fileName;
        private CheckBox checkBox1;
        private int globalTimer;
        private Button btnChange;
        private Button btnOpen;
        private int globalInterval;
        private Button btnAbout;
        private NotifyIcon notifyIcon1;
        private ContextMenu contextMenu1;
        private MenuItem menuItem1;
        private MenuItem menuItem2;
        private Dictionary<RadioButton, int> myArray;
        private MenuItem menuItem3;
        private RadioButton rbt1min;
        private RadioButton rbt5min;
        private RadioButton rbt15min;
        private RadioButton rbt1hr;
        private RadioButton rbt2hr;
        private RadioButton rbt12hr;
        private RadioButton rbt1day;
        private GroupBox groupBox1;
        private Settings mySetting;

        public int GlobalInterval
        {
            get { return globalInterval; }
            set { globalInterval = value; }
        }

        public List<string> Files
        {
            get
            {
                List<string> result = new List<string>();
                foreach (var item in mycheckedListBox.Items)
                {
                    result.Add(item.ToString());
                }
                return result;
            }

            set
            {
                mycheckedListBox.Items.Clear();
                foreach (var item in value)
                {
                    mycheckedListBox.Items.Add(item, true);
                }
            }
        }

        public FrmMain()
        {
            InitializeComponent();

            myArray = new Dictionary<RadioButton, int>()
            {
                {rbt1min, 60},
                {rbt5min, 180},
                {rbt15min, 540},
                {rbt1hr, 3600},
                {rbt2hr, 7200},
                {rbt12hr, 43200},
                {rbt1day, 86400}
            };

            picIndex = 0;
            globalTimer = 0;

            mySetting = new Settings(Directory.GetCurrentDirectory(), this);

        }

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                notifyIcon1.Visible = false;
                if (components != null)
                {
                    components.Dispose();
                }
            }

            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmMain));
            this.btnChange = new System.Windows.Forms.Button();
            this.openFileDialog1 = new System.Windows.Forms.OpenFileDialog();
            this.btnOpen = new System.Windows.Forms.Button();
            this.mycheckedListBox = new System.Windows.Forms.CheckedListBox();
            this.btnDel = new System.Windows.Forms.Button();
            this.timer1 = new System.Windows.Forms.Timer(this.components);
            this.checkBox1 = new System.Windows.Forms.CheckBox();
            this.btnAbout = new System.Windows.Forms.Button();
            this.notifyIcon1 = new System.Windows.Forms.NotifyIcon(this.components);
            this.contextMenu1 = new System.Windows.Forms.ContextMenu();
            this.menuItem1 = new System.Windows.Forms.MenuItem();
            this.menuItem2 = new System.Windows.Forms.MenuItem();
            this.menuItem3 = new System.Windows.Forms.MenuItem();
            this.rbt1min = new System.Windows.Forms.RadioButton();
            this.rbt5min = new System.Windows.Forms.RadioButton();
            this.rbt15min = new System.Windows.Forms.RadioButton();
            this.rbt1hr = new System.Windows.Forms.RadioButton();
            this.rbt2hr = new System.Windows.Forms.RadioButton();
            this.rbt12hr = new System.Windows.Forms.RadioButton();
            this.rbt1day = new System.Windows.Forms.RadioButton();
            this.groupBox1 = new System.Windows.Forms.GroupBox();
            this.groupBox1.SuspendLayout();
            this.SuspendLayout();
            // 
            // btnChange
            // 
            this.btnChange.Location = new System.Drawing.Point(64, 8);
            this.btnChange.Name = "btnChange";
            this.btnChange.Size = new System.Drawing.Size(64, 24);
            this.btnChange.TabIndex = 0;
            this.btnChange.Text = "Change";
            this.btnChange.Click += new System.EventHandler(this.btnChange_Click);
            // 
            // openFileDialog1
            // 
            this.openFileDialog1.Multiselect = true;
            // 
            // btnOpen
            // 
            this.btnOpen.Location = new System.Drawing.Point(8, 8);
            this.btnOpen.Name = "btnOpen";
            this.btnOpen.Size = new System.Drawing.Size(48, 24);
            this.btnOpen.TabIndex = 2;
            this.btnOpen.Text = "&Open";
            this.btnOpen.Click += new System.EventHandler(this.btnOpen_Click);
            // 
            // mycheckedListBox
            // 
            this.mycheckedListBox.AllowDrop = true;
            this.mycheckedListBox.ColumnWidth = 300;
            this.mycheckedListBox.HorizontalScrollbar = true;
            this.mycheckedListBox.Location = new System.Drawing.Point(8, 48);
            this.mycheckedListBox.Name = "mycheckedListBox";
            this.mycheckedListBox.Size = new System.Drawing.Size(306, 229);
            this.mycheckedListBox.Sorted = true;
            this.mycheckedListBox.TabIndex = 3;
            this.mycheckedListBox.SelectedIndexChanged += new System.EventHandler(this.mycheckedListBox_SelectedIndexChanged);
            this.mycheckedListBox.DragDrop += new System.Windows.Forms.DragEventHandler(this.mycheckedListBox_DragDrop);
            this.mycheckedListBox.DragEnter += new System.Windows.Forms.DragEventHandler(this.mycheckedListBox_DragEnter);
            // 
            // btnDel
            // 
            this.btnDel.Location = new System.Drawing.Point(136, 8);
            this.btnDel.Name = "btnDel";
            this.btnDel.Size = new System.Drawing.Size(64, 24);
            this.btnDel.TabIndex = 4;
            this.btnDel.Text = "Delete";
            this.btnDel.Click += new System.EventHandler(this.btnDel_Click);
            // 
            // timer1
            // 
            this.timer1.Enabled = true;
            this.timer1.Interval = 5000;
            this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
            // 
            // checkBox1
            // 
            this.checkBox1.Location = new System.Drawing.Point(320, 239);
            this.checkBox1.Name = "checkBox1";
            this.checkBox1.Size = new System.Drawing.Size(112, 43);
            this.checkBox1.TabIndex = 6;
            this.checkBox1.Text = "Random Order (Shuffle Mode)";
            // 
            // btnAbout
            // 
            this.btnAbout.Location = new System.Drawing.Point(368, 8);
            this.btnAbout.Name = "btnAbout";
            this.btnAbout.Size = new System.Drawing.Size(64, 24);
            this.btnAbout.TabIndex = 8;
            this.btnAbout.Text = "About";
            this.btnAbout.Click += new System.EventHandler(this.btnAbout_Click);
            // 
            // notifyIcon1
            // 
            this.notifyIcon1.BalloonTipIcon = System.Windows.Forms.ToolTipIcon.Info;
            this.notifyIcon1.BalloonTipText = "Double-click to add or remove images to the list or modify the interval between c" +
                "hanges";
            this.notifyIcon1.BalloonTipTitle = "Wallpaper Rotator";
            this.notifyIcon1.ContextMenu = this.contextMenu1;
            this.notifyIcon1.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyIcon1.Icon")));
            this.notifyIcon1.Text = "Wallpaper Rotator";
            this.notifyIcon1.Visible = true;
            this.notifyIcon1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.notifyIcon1_MouseMove);
            this.notifyIcon1.DoubleClick += new System.EventHandler(this.notifyIcon1_DoubleClick);
            // 
            // contextMenu1
            // 
            this.contextMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.menuItem1,
            this.menuItem2,
            this.menuItem3});
            // 
            // menuItem1
            // 
            this.menuItem1.Index = 0;
            this.menuItem1.Text = "E&xit";
            this.menuItem1.Click += new System.EventHandler(this.menuItem1_Click);
            // 
            // menuItem2
            // 
            this.menuItem2.Index = 1;
            this.menuItem2.Text = "&Restore";
            this.menuItem2.Click += new System.EventHandler(this.menuItem2_Click);
            // 
            // menuItem3
            // 
            this.menuItem3.Index = 2;
            this.menuItem3.Text = "&Change";
            this.menuItem3.Click += new System.EventHandler(this.menuItem3_Click);
            // 
            // rbt1min
            // 
            this.rbt1min.AutoSize = true;
            this.rbt1min.Location = new System.Drawing.Point(6, 19);
            this.rbt1min.Name = "rbt1min";
            this.rbt1min.Size = new System.Drawing.Size(65, 17);
            this.rbt1min.TabIndex = 10;
            this.rbt1min.TabStop = true;
            this.rbt1min.Text = "1 minute";
            this.rbt1min.UseVisualStyleBackColor = true;
            this.rbt1min.CheckedChanged += new System.EventHandler(this.IntervalChanged);
            // 
            // rbt5min
            // 
            this.rbt5min.AutoSize = true;
            this.rbt5min.Location = new System.Drawing.Point(6, 43);
            this.rbt5min.Name = "rbt5min";
            this.rbt5min.Size = new System.Drawing.Size(70, 17);
            this.rbt5min.TabIndex = 11;
            this.rbt5min.TabStop = true;
            this.rbt5min.Text = "5 minutes";
            this.rbt5min.UseVisualStyleBackColor = true;
            this.rbt5min.CheckedChanged += new System.EventHandler(this.IntervalChanged);
            // 
            // rbt15min
            // 
            this.rbt15min.AutoSize = true;
            this.rbt15min.Location = new System.Drawing.Point(6, 67);
            this.rbt15min.Name = "rbt15min";
            this.rbt15min.Size = new System.Drawing.Size(76, 17);
            this.rbt15min.TabIndex = 12;
            this.rbt15min.TabStop = true;
            this.rbt15min.Text = "15 minutes";
            this.rbt15min.UseVisualStyleBackColor = true;
            this.rbt15min.CheckedChanged += new System.EventHandler(this.IntervalChanged);
            // 
            // rbt1hr
            // 
            this.rbt1hr.AutoSize = true;
            this.rbt1hr.Location = new System.Drawing.Point(6, 91);
            this.rbt1hr.Name = "rbt1hr";
            this.rbt1hr.Size = new System.Drawing.Size(55, 17);
            this.rbt1hr.TabIndex = 13;
            this.rbt1hr.TabStop = true;
            this.rbt1hr.Text = "1 hour";
            this.rbt1hr.UseVisualStyleBackColor = true;
            this.rbt1hr.CheckedChanged += new System.EventHandler(this.IntervalChanged);
            // 
            // rbt2hr
            // 
            this.rbt2hr.AutoSize = true;
            this.rbt2hr.Location = new System.Drawing.Point(6, 115);
            this.rbt2hr.Name = "rbt2hr";
            this.rbt2hr.Size = new System.Drawing.Size(60, 17);
            this.rbt2hr.TabIndex = 14;
            this.rbt2hr.TabStop = true;
            this.rbt2hr.Text = "2 hours";
            this.rbt2hr.UseVisualStyleBackColor = true;
            this.rbt2hr.CheckedChanged += new System.EventHandler(this.IntervalChanged);
            // 
            // rbt12hr
            // 
            this.rbt12hr.AutoSize = true;
            this.rbt12hr.Location = new System.Drawing.Point(6, 139);
            this.rbt12hr.Name = "rbt12hr";
            this.rbt12hr.Size = new System.Drawing.Size(66, 17);
            this.rbt12hr.TabIndex = 15;
            this.rbt12hr.TabStop = true;
            this.rbt12hr.Text = "12 hours";
            this.rbt12hr.UseVisualStyleBackColor = true;
            this.rbt12hr.CheckedChanged += new System.EventHandler(this.IntervalChanged);
            // 
            // rbt1day
            // 
            this.rbt1day.AutoSize = true;
            this.rbt1day.Location = new System.Drawing.Point(6, 163);
            this.rbt1day.Name = "rbt1day";
            this.rbt1day.Size = new System.Drawing.Size(51, 17);
            this.rbt1day.TabIndex = 16;
            this.rbt1day.TabStop = true;
            this.rbt1day.Text = "1 day";
            this.rbt1day.UseVisualStyleBackColor = true;
            this.rbt1day.CheckedChanged += new System.EventHandler(this.IntervalChanged);
            // 
            // groupBox1
            // 
            this.groupBox1.Controls.Add(this.rbt1day);
            this.groupBox1.Controls.Add(this.rbt1min);
            this.groupBox1.Controls.Add(this.rbt12hr);
            this.groupBox1.Controls.Add(this.rbt5min);
            this.groupBox1.Controls.Add(this.rbt2hr);
            this.groupBox1.Controls.Add(this.rbt15min);
            this.groupBox1.Controls.Add(this.rbt1hr);
            this.groupBox1.Location = new System.Drawing.Point(320, 48);
            this.groupBox1.Name = "groupBox1";
            this.groupBox1.Size = new System.Drawing.Size(112, 185);
            this.groupBox1.TabIndex = 17;
            this.groupBox1.TabStop = false;
            this.groupBox1.Text = "Change Every:";
            // 
            // FrmMain
            // 
            this.AllowDrop = true;
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(440, 287);
            this.Controls.Add(this.btnAbout);
            this.Controls.Add(this.checkBox1);
            this.Controls.Add(this.btnDel);
            this.Controls.Add(this.mycheckedListBox);
            this.Controls.Add(this.btnOpen);
            this.Controls.Add(this.btnChange);
            this.Controls.Add(this.groupBox1);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
            this.HelpButton = true;
            this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
            this.MaximizeBox = false;
            this.Name = "FrmMain";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.Text = "Wallpaper Rotator";
            this.WindowState = System.Windows.Forms.FormWindowState.Minimized;
            this.Load += new System.EventHandler(this.Form1_Load);
            this.Resize += new System.EventHandler(this.Form1_Resize);
            this.groupBox1.ResumeLayout(false);
            this.groupBox1.PerformLayout();
            this.ResumeLayout(false);

        }
        #endregion

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.Run(new FrmMain());
        }

        /// <summary>
        /// Change the wallpaper immediately. the method search for any image file in
        /// the directory and enter them into an checked list box
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnChange_Click(object sender, System.EventArgs e)
        {
            SetBMP();
        }

        /// <summary>
        /// update the ini file with the picture index
        /// </summary>
        private void UpdateFile()
        {
            mySetting.SaveSettings();

        }

        /// <summary>
        /// add an image file into the checked listbox
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnOpen_Click(object sender, System.EventArgs e)
        {
            //change the initial directory if required.
            openFileDialog1.InitialDirectory = @"c:\";
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                foreach (string fileName in openFileDialog1.FileNames)
                {
                    mycheckedListBox.Items.Add(fileName, CheckState.Checked);
                }
                UpdateFile();
            }

        }

        /// <summary>
        /// form load
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, System.EventArgs e)
        {
            this.Hide();
            globalInterval = 12;
            mySetting.LoadSettings();

            foreach (var item in myArray)
            {
                if (item.Value == globalInterval * 5)
                {
                    item.Key.Checked = true;
                }
            }

            if (mycheckedListBox.Items.Count > picIndex)
            {
                mycheckedListBox.SelectedIndex = picIndex;
            }

            if (mycheckedListBox.Items.Count > 0)
            {
                fileName = mycheckedListBox.Items[picIndex].ToString();
            }
            else
            {
                this.Show();
                this.WindowState = FormWindowState.Normal;
            }
            
            SetBMP();
        }

        /// <summary>
        /// add a selected file type to the listbox
        /// if a new type is suppose to be added - please enter it here
        /// </summary>
        /// <param name="fileType">the file type to be added</param>
        /// <param name="mycheckedListBox"></param>
        /// <returns></returns>
        private void AddAllSupportedTypes(string dir)
        {
            AddToCheckedListBox("*.jpg", dir);
            AddToCheckedListBox("*.jpeg", dir);
            AddToCheckedListBox("*.bmp", dir);
            AddToCheckedListBox("*.gif", dir);


        }
        /// <summary>
        /// check the directory , collect all the file name of a certain type
        /// and send them to AddToListBox
        /// </summary>
        /// <param name="fileType">image type file</param>
        /// <param name="dir">the selected directory</param>
        private void AddToCheckedListBox(string fileType, string dir)
        {
            string[] dirs = Directory.GetFiles(dir, fileType);

            AddToListBox(dirs);

        }
        /// <summary>
        /// add the string[] to the list box
        /// </summary>
        /// <param name="files">the array of strings to be added</param>
        private void AddToListBox(string[] files)
        {
            foreach (string file in files)
            {
                mycheckedListBox.Items.Add(file, CheckState.Checked);
                Trace.WriteLine("adding : " + file);
            }
        }
        private void AddToListBox(string file)
        {
            {
                mycheckedListBox.Items.Add(file, CheckState.Checked);
                Trace.WriteLine("adding : " + file);
            }
        }
        /// <summary>
        /// get all the directorys in the specific directory and send them
        /// to check all files and sub directories
        /// </summary>
        /// <param name="strDir">the directory to be searched in</param>
        private void checkDir(string strDir)
        {
            string[] strTempDir = Directory.GetDirectories(strDir);
            foreach (string newstr in strTempDir)
            {
                checkDir(newstr);
            }

            AddAllSupportedTypes(strDir);
        }

        public bool m_bcheckChangePossible = true;
        private void mycheckedListBox_SelectedIndexChanged(object sender, System.EventArgs e)
        {
            if (m_bcheckChangePossible)
                fileName = mycheckedListBox.SelectedItem.ToString();
        }

        /// <summary>
        /// Delete picture from the listbox
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnDel_Click(object sender, System.EventArgs e)
        {
            if (mycheckedListBox.Items.Count < 1)
                return;
            if (mycheckedListBox.SelectedIndex < 0)
            {
                return;
            }
            m_bcheckChangePossible = false;
            int Index = mycheckedListBox.SelectedIndex;
            mycheckedListBox.Items.RemoveAt(Index);
            fileName = mycheckedListBox.SelectedIndex.ToString();
            m_bcheckChangePossible = true;
        }

        /// <summary>
        /// machine clock
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer1_Tick(object sender, System.EventArgs e)
        {
            if (globalInterval < 0) return;
            if (globalTimer++ > globalInterval)
            {
                SetBMP();
                globalTimer = 0;
            }
        }
        /// <summary>
        /// Set the new BMP in the background
        /// </summary>
        private void SetBMP()
        {
            try
            {
                int nResult;
                if (mycheckedListBox.Items.Count < 1)
                    return;
                picIndex = mycheckedListBox.SelectedIndex;
                if (picIndex < 0)
                {

                    picIndex = 0;
                    mycheckedListBox.SelectedIndex = 0;
                }

                if (Path.GetExtension(fileName).ToLower() != ".bmp")
                {
                    Bitmap theImage = new Bitmap(fileName);
                    fileName = Path.Combine(mySetting.m_settingsPath, "new.bmp");
                    theImage.Save(fileName, System.Drawing.Imaging.ImageFormat.Bmp);
                    theImage.Dispose();
                }

                nResult = WinAPI.SystemParametersInfo(SPI_SETDESKWALLPAPER, 1, fileName, SPIF_SENDCHANGE);
                picIndex = (picIndex + 1) % mycheckedListBox.CheckedItems.Count;
                if (checkBox1.Checked == true)
                {
                    Random rnd = new Random();
                    picIndex = (rnd.Next(mycheckedListBox.CheckedItems.Count) %
                        mycheckedListBox.CheckedItems.Count);
                }
                mycheckedListBox.SelectedIndex = picIndex;

                UpdateFile();
            }
            catch (Exception ex)
            {
                Trace.WriteLine(ex.ToString());
            }
        }

        private void cmbInterval_SelectedIndexChanged(object sender, System.EventArgs e)
        {
            //GlobalInterval = myArray[cmbInterval.SelectedIndex]  / 5;
            globalTimer = 0;
            UpdateFile();
        }

        private void btnAbout_Click(object sender, System.EventArgs e)
        {
            FrmAbout myfrmAbout = new FrmAbout();
            myfrmAbout.ShowDialog(this);
        }

        private void mycheckedListBox_DragDrop(object sender, DragEventArgs e)
        {
            Trace.WriteLine("ListBox Drag enter");

            string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);

            foreach (string dirfile in files)
            {
                if (CheckIfDirectory(dirfile))
                    checkDir(dirfile);
                else
                    AddToListBox(dirfile);
            }

            Trace.WriteLine("After Sending to listbox");

        }
        private bool CheckIfDirectory(string dir)
        {
            bool bAns = false;
            if (File.GetAttributes(dir) == FileAttributes.Directory)
                bAns = true;
            return bAns;
        }

        private void mycheckedListBox_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop, false) == true)
                e.Effect = DragDropEffects.All;
            Trace.WriteLine("ListBoxDragDrop   ");
        }

        private void notifyIcon1_DoubleClick(object sender, System.EventArgs e)
        {
            this.Show();
            this.WindowState = FormWindowState.Normal;
        }

        private void menuItem1_Click(object sender, System.EventArgs e)
        {
            this.Close();
        }

        private void menuItem2_Click(object sender, System.EventArgs e)
        {
            this.Show();
            this.WindowState = FormWindowState.Normal;
        }

        private void Form1_Resize(object sender, System.EventArgs e)
        {
            if (WindowState == FormWindowState.Minimized)
                this.Hide();

        }

        private void menuItem3_Click(object sender, System.EventArgs e)
        {
            btnChange_Click(sender, e);

        }

        private void IntervalChanged(object sender, EventArgs e)
        {
            if (sender is RadioButton && ((RadioButton)sender).Checked)
            {
                globalInterval = myArray[(RadioButton)sender] / 5;
                globalTimer = 0;
                UpdateFile();
            }
        }

        private void notifyIcon1_MouseMove(object sender, MouseEventArgs e)
        {
            if (!this.Visible && this.mycheckedListBox.Items.Count == 0)
            {
                this.notifyIcon1.ShowBalloonTip(10000, "No images selected!", "Add some images to the list to\nstart switching them in your desktop!", ToolTipIcon.Warning);
            }
        }
    }
}
